package com.huajx.core.server;

import com.huajx.core.config.HbootConfigManager;
import com.huajx.core.server.annonation.MinaServer;
import com.huajx.core.server.config.HbootServerConfig;
import com.huajx.util.ClassUtil;
import com.huajx.util.ObjectUtil;
import com.huajx.util.ReflectUtil;
import com.huajx.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * Hoot服务处理
 */
public class HbootServerManager {
    private final Logger logger = LoggerFactory.getLogger(HbootServerManager.class);

    private final static HbootServerManager manager = new HbootServerManager();

    private final static Map<String, HbootServerInfo> serverInfos = new LinkedHashMap<>();
    private final static Map<String, HbootServer> servers = new LinkedHashMap<>();

    public static HbootServerManager me() {
        return manager;
    }

    /**
     * 扫描所有HbootServer子类
     */
    public void scan() {
        logger.debug("服务扫描开始");
        Set<Class<?>> classes = ClassUtil.scanPackageBySuper(null, HbootServer.class);

//        HbootServerConfig config = null;

        MinaServer server = null;

        logger.debug("Scan HbootServer 服务器");
        for (Class<?> clazz : classes) {
            Class<HbootServer> serverClass = (Class<HbootServer>) clazz;

            server = serverClass.getAnnotation(MinaServer.class);

            if (server == null) {
                continue;
            }

            String serverName = server.name();

            if (StrUtil.isBlank(serverName)) {
                serverName = StrUtil.lowerFirst(clazz.getSimpleName());
            }

//            logger.info("正在启动服务: {}", serverName);
            HbootServerInfo info = new HbootServerInfo();

            info.setName(serverName);
            info.setPort(server.port());
            info.setServerClass(serverClass);

            serverInfos.put(serverName, info);

        }
        logger.debug("服务扫描结束");
    }

    public void start() {
        if (ObjectUtil.notEmpty(servers)) {
            for (Map.Entry<String, HbootServer> serverEntry : servers.entrySet()) {
                HbootServer server = serverEntry.getValue();
                if (server == null) {
                    continue;
                }
                if (!server.isRunning()) {
                    server.start();
                }
            }

            return;
        }

        for (Map.Entry<String, HbootServerInfo> entry : serverInfos.entrySet()) {
            String key = entry.getKey();

            HbootServerInfo info = entry.getValue();
            Class<? extends HbootServer> clazz = info.getServerClass();

            String name = info.getName();
            int port = info.getPort();

            Map<String, HbootServerConfig> configs = HbootConfigManager.me().get(HbootServerConfig.class, key);

            for (Map.Entry<String, HbootServerConfig> configEntry : configs.entrySet()) {
                HbootServer server = ReflectUtil.newInstance(clazz);

                HbootServerConfig config = configEntry.getValue();

                if (config.getPort() <= 80) {
                    config.setPort(port);
                }

                if (StrUtil.isBlank(config.getName())) {
                    config.setName(name);
                }

                String configName = configEntry.getKey();

                server.config(config);

//                logger.info("{}正在启动服务,{}", name, port);
                try {
                    server.start();
                } catch (Throwable e) {
                    logger.error("启动异常", e);
                }
                servers.put(configName, server);
            }
//            logger.info("配置信息:{}", configs);
        }
//        logger.info("所有服务，启动完毕");

    }

    public void stop() {
        for (Map.Entry<String, HbootServer> serverEntry : servers.entrySet()) {
            HbootServer server = serverEntry.getValue();
            if (server == null) {
                continue;
            }
            if (server.isRunning()) {
                server.stop();
            }
        }
    }
}
